//
// Created by QU on 2024/4/29.
//

#include <functional>
#include <iostream>
#include <utility>
#include <map>
#include <string>

using namespace std;

int add(int a, int b) { return a + b; }

auto mod = [](int a, int b) { return a % b; };

// 如果你想使用类作 operator(). 不要忘记public: , 默认情况下使用的是private的访问修饰符.
// 可能出现调用不了的情况.
class divide {
public:
    int operator()(int a, int b) {
        return a / b;
    }
};
// 如果使用struct就没有设个B事.

int main() {
    map<string, function<int(int, int)>> binops;
    // 定义一个操作符, 对应一个函数操作.
//    binops["+"] = add;
//    binops["%"] = mod;
//    binops["/"] = divide;

//    map中的指定类型的函数接受不了上面的可调用类型
//    在c++中抽象了一种可调用对象的调用, function类是一个 模板类,定义在functional头文件中

    function<int(int,int)> f1 = add;
    function<int(int,int)> f2 = std::minus<>();
    function<int(int,int)> f3 = [](int a, int b){ return a*b; };
    function<int(int,int)> f4 = divide();
    function<int(int,int)> f5 = mod;

    binops["+"] = f1;
    binops["-"] = f2;
    binops["*"] = f3;
    binops["/"] = f4;
    binops["%"] = f5;

    while (true) {
        std::string op;
        std::cout << "Enter an operator (+, -, *, /, %) or 'q' to quit: ";
        std::cin >> op;

        if (op == "q") {
            break;
        } else if (binops.find(op) != binops.end()) {
            int a, b;
            std::cout << "Enter two integers: ";
            std::cin >> a >> b;
 
            try {
                std::cout << "Result: " << binops[op](a, b) << std::endl;
            } catch (const std::invalid_argument& e) {
                std::cerr << "Error: " << e.what() << std::endl;
            }
        } else {
            std::cerr << "Invalid operator!" << std::endl;
        }
    }

    return 0;
}
